package operator.transfer;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import entity.Like;
import entity.People;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import util.DataUtil;
import util.Printer;
import util.ThreadHelper;

class FlatMapOperator {

    public static void main(String[] args) {
//        testMap();
//        flatMap1();
//        flatMap2();
        flatMap3();
//        flatMapIterable();
    }

    public static void testMap() {
        List<People> ps = DataUtil.createPeoples();
        Observable.fromIterable(ps)
                .map(new Function<People, List<Like>>() {
                    @Override
                    public List<Like> apply(People people) throws Exception {
                        return people.likes;
                    }
                })
                .subscribe(new Consumer<List<Like>>() {
                    @Override
                    public void accept(List<Like> likes) throws Exception {
                        for (Like like : likes) {
                            Printer.print(like.name);
                        }
                    }
                });
    }

    //避免循环嵌套
    static void flatMap1() {
        List<People> ps = DataUtil.createPeoples();
        Observable.fromIterable(ps)
                .flatMap(new Function<People, ObservableSource<Like>>() {
                    @Override
                    public ObservableSource<Like> apply(People people) throws Exception {
                        return Observable.fromIterable(people.likes);
                    }
                }).subscribe(new Consumer<Like>() {
            @Override
            public void accept(Like like) throws Exception {
                Printer.print(like.name);
            }
        });
    }

    //使用flatMap化解接口嵌套
    static void flatMap2() {
        queryIdByPin("chenlong")
                .flatMap(new Function<Integer, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(Integer integer) throws Exception {
                        return Observable.just("天津市政大厅");
                    }
                }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Printer.print(s);
            }
        });
    }

    //无序性
    static void flatMap3() {
        Observable.just(Arrays.asList(1, 2, 3, 4, 5), Arrays.asList(6, 7))
                .flatMap(new Function<List<Integer>, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(List<Integer> list) throws Exception {
                        return Observable.fromIterable(list).delay(list.size(), TimeUnit.SECONDS);
                    }
                })
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Printer.print(integer.toString());
                    }
                });
        ThreadHelper.sleep();
    }


    static void flatMapIterable() {
        List<People> ps = DataUtil.createPeoples();
        Observable.fromIterable(ps)
                .flatMapIterable(new Function<People, Iterable<Like>>() {
                    @Override
                    public Iterable<Like> apply(People people) throws Exception {
                        return people.likes;
                    }
                })
                .subscribe(new Consumer<Like>() {
                    @Override
                    public void accept(Like like) throws Exception {
                        Printer.print(like.name);
                    }
                });
    }


    static Observable<Integer> queryIdByPin(String pin){
        return Observable.just(pin)
                .flatMap(new Function<String, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(String s) throws Exception {
                        return Observable.just(1);
                    }
                });
    }


}
